﻿using System;
using System.Collections.Generic;
using STeaL.Functional;

namespace STeaL.Algorithm {
  public static partial class IListExtensions {
#region is_sorted_until
    public static int is_sorted_until<T>(this IList<T> list, int first, int last, Func<T,T,bool> pred ) {
      if ( first != last )
        for ( int next = first; ++next != last; ++first)
          if ( pred(list[next], list[first] ) )
            return next;
      return last;
    }

    public static int is_sorted_until<T>(this IList<T> list, int first, int last) where T : IComparable<T> {
      return is_sorted_until(list, first, last, rel_op.less<T>);
    }

    public static int is_sorted_until<T>(this IList<T> list, Func<T,T,bool> pred ) {
      return is_sorted_until(list, 0, list.Count, pred);
    }

    public static int is_sorted_until<T>(this IList<T> list) where T : IComparable<T> {
        return is_sorted_until(list, 0, list.Count, rel_op.less<T>);
    }

#endregion
#region is_sorted
    public static bool is_sorted<T>(this IList<T> list, int first, int last, Func<T, T, bool> pred) {
      return is_sorted_until(list, first, last, pred) == last;
    }

    public static bool is_sorted<T>(this IList<T> list, int first, int last) where T : IComparable<T> {
        return is_sorted_until(list, first, last, rel_op.less<T>) == last;
    }

    public static bool is_sorted<T>(this IList<T> list, Func<T, T, bool> pred) {
      return is_sorted_until(list, 0, list.Count, pred) == list.Count;
    }

    public static bool is_sorted<T>(this IList<T> list) where T : IComparable<T> {
        return is_sorted_until(list, 0, list.Count, rel_op.less<T>) == list.Count;
    }

#endregion
  }
}
